/**
 * @author dnk2
 */

var highlightMatches = true ;
var openMatches = false ;

 
 function KoruGame() {
	logDebug("Koru Game created");
	
	this.koru ;
	this.mask ;
	this.messageBox ;
	this.player ;
	this.xmlHttp ;
	
	this.task_id ;
	this.task_title ;
	this.task_desc ;
	this.task_narr ;
	this.task_docs ;
	
	this.scoreBoard ;
	this.score_query ;
	this.score_rank ;
	
	this.taskPanel ;
	this.taskText ;
	this.ranking ;
	
	//this.timeBonus ;
	
	this.docsLocated ;
	this.docsOpened ;
	this.score = 0 ;
	
	var timer ;
}

KoruGame.prototype.init = koruGame_init ;
KoruGame.prototype.hideTaskText = koruGame_hideTaskText ;
KoruGame.prototype.toggleTaskText = koruGame_toggleTaskText ;

KoruGame.prototype.resize = koruGame_resize ;
KoruGame.prototype.showMessage = koruGame_showMessage ;
KoruGame.prototype.showLoginMessage = koruGame_showLoginMessage ;
KoruGame.prototype.showWelcomeMessage = koruGame_showWelcomeMessage ;

KoruGame.prototype.requestTask = koruGame_requestTask ;
KoruGame.prototype.processTaskResponse = koruGame_processTaskResponse ;
KoruGame.prototype.start = koruGame_start ;

KoruGame.prototype.documentLocated = koruGame_documentLocated ;
KoruGame.prototype.documentOpened = koruGame_documentOpened ;

KoruGame.prototype.postQueryScore = koruGame_postQueryScore ;

KoruGame.prototype.requestEndGame = koruGame_requestEndGame ;
KoruGame.prototype.processEndResponse = koruGame_processEndResponse ;

function koruGame_init() {
	try {
		this.id = "KoruGame" ;
		
		this.koru = document.applyInherit(document.createElement("div"), new Koru()) ;
		this.appendChild(this.koru) ;
		this.koru.init() ;
			
		// score stuff
		
		this.scoreBoard = document.createElement("div") ;
		this.scoreBoard.id = "scoreBoard" ;
		this.scoreBoard.onmouseover = new Function("koruGame.task_tooltip.style.display='block' ; ") ;	
		this.scoreBoard.onmouseout = new Function("event", "if (isMouseLeaveOrEnter(event, this)) koruGame.task_tooltip.style.display = 'none'") ;
		this.appendChild(this.scoreBoard) ;
		
		this.score_query = document.createElement("div") ;
		this.score_query.className = "query" ;	
		
		//this.score_query.innerHTML = "Best Query <br /> <em>200</em> pts</br>" ;
		this.scoreBoard.appendChild(this.score_query) ;
		
		this.score_rank = document.createElement("div") ;
		this.score_rank.className = "ranking" ;
		this.scoreBoard.appendChild(this.score_rank) ;		
		
		this.currQueryScore = document.createElement("div") ;
		this.currQueryScore.className = "currQueryScore" ;
		this.currQueryScore.onmouseover = new Function("koru.queryResultsTray.score_tooltip.style.display='block' ; ") ;	
		this.currQueryScore.onmouseout = new Function("event", "if (isMouseLeaveOrEnter(event, this)) koru.queryResultsTray.score_tooltip.style.display = 'none'") ;
		//this.currQueryScore.innerHTML = "<em>200</em> pts" ;
		this.appendChild(this.currQueryScore) ;	
			
			
		// task stuff
		
		this.taskPanel = document.createElement("div") ;
		this.taskPanel.id = "taskPanel" ;
		this.taskPanel.innerHTML = "Current Task:" ;
		this.appendChild(this.taskPanel) ;
		
		var tl = document.createElement("div") ;
		tl.className = "left" ;
		this.taskPanel.appendChild(tl) ;
		
		var tr = document.createElement("div") ;
		tr.className = "right" ;
		this.taskPanel.appendChild(tr) ;
		
		this.taskText = document.createElement("div") ;
		this.taskText.onmouseout = new Function("event", "if (isMouseLeaveOrEnter(event, this)) koruGame.hideTaskText() ;") ;
		this.taskText.className = "taskText_less" ;
		this.taskText.innerHTML = "loading..." ;
		this.taskPanel.appendChild(this.taskText) ;
		
		this.moreInfo = document.createElement("div") ;
		this.moreInfo.onclick = new Function("koruGame.toggleTaskText() ;") ;
		this.moreInfo.className = "moreInfo" ;
		this.moreInfo.innerHTML = "more" ;
		this.taskPanel.appendChild(this.moreInfo) ;
		
		var end = document.createElement("div") ;
		end.onclick = new Function("window.location.href=\"tasks.htm\"") ;
		end.className = "endGame" ;
		end.innerHTML = "Quit" ;
		this.appendChild(end) ;
		
		this.mask = document.createElement("div") ;
		this.mask.id = "mask" ;
		this.mask.style.display = "none" 
		this.appendChild(this.mask) ;
		
		this.docsLocated = new Array() ;
		this.docsOpened = new Array() ;
		
		this.task_tooltip = document.createElement("div") ;
		this.task_tooltip.id = "task_tooltip" ;
		this.task_tooltip.onmouseout = new Function("event", "if (isMouseLeaveOrEnter(event, this)) koruGame.task_tooltip.style.display = 'none'") ;
		this.appendChild(this.task_tooltip) ;
	
		this.player = readCookie("koru_user") ;
		 
		if (this.player==null || this.player=="") {
			this.showLoginMessage() ;
		} else {
			this.requestTask() ;
		}
		
	} catch ( e ) { 
		logError("koruGame.init.error: " + e ); 
		throw (e) ;
	}
} 

function koruGame_hideTaskText() {
	this.taskText.className = "taskText_less" ;
	this.moreInfo.innerHTML = "more" ;
}

function koruGame_toggleTaskText() {
	
	if (this.taskText.className == "taskText_less") {
		this.taskText.className = "taskText_more" ;
		this.moreInfo.innerHTML = "less" ;
	} else {
		this.taskText.className = "taskText_less" ;
		this.moreInfo.innerHTML = "more" ;
	}
}

function koruGame_requestTask() {

	var taskId = getUrlParam("task") ;
	
	var parTask = newElementAtt('param', '', new Array('name', 'value'), new Array('taskId', taskId) ) ;
	var parPlayer = newElementAtt('param', '', new Array('name', 'value'), new Array('player', this.player) ) ;
	
	var paramList = newElement('paramList', parTask + parPlayer);
	
  	var request = newElementAtt('request', paramList, new Array('lang', 'to', 'type', 'uid'), new Array('en',collection + '/GetTask', 'process', '1'  ) );
  	var message = newElement('message', request );
  	var soapMessage = messageToSOAP(message);
   
  	this.xmlHttp = XmlHttp.create();
  	this.xmlHttp.open("POST", "http://" + serverPath + "/services/localsite", true);
  	this.xmlHttp.onreadystatechange = new Function("koruGame.processTaskResponse() ; ") ;
   
	this.xmlHttp.setRequestHeader("SOAPAction", "\"\"");
  	this.xmlHttp.setRequestHeader("Content-Type", "Content-Type: text/xml; charset=utf-8");
   
   	logDebug("Request: " + message) ;
   
  	this.xmlHttp.send(soapMessage);
}

function koruGame_processTaskResponse() {
	if (this.xmlHttp.readyState == 4) {
		logDebug("Task Response: " + this.xmlHttp.responseXML.xml) ;
		
		var task = this.xmlHttp.responseXML.getElementsByTagName('task')[0];
		
		
		if (task != null) {
			this.task_id = task.getAttribute("id") ;
			this.task_title = task.getAttribute("title") ;
			this.task_desc = task.getAttribute("description") ;
			this.task_narr = task.getAttribute("narrative") ;
			
			//this.taskText.innerHTML = this.task_desc + this.task_narr ;
			this.task_docs = task.getAttribute('relevantDocs') ;
			
			var taskScore = task.getElementsByTagName('taskScore')[0] ;
			this.score = taskScore.getAttribute("score") ;
			if (this.score != null) {
				this.score_query.innerHTML = "Best Query <br /> <em>" + this.score + "</em> pts" ;
				this.score_rank.innerHTML = taskScore.getAttribute("rank") ;
				
				var dr = taskScore.getAttribute("docs_returned") ;
				var rdr = taskScore.getAttribute("rel_docs_returned") ;
				var rdt = taskScore.getAttribute("rel_docs_total") ;
				var rc = rdr/rdt ;
				var pc = rdr/dr ;			
				
				var str = "<em>" + rdr + "</em> of <em>" + dr + "</em> returned documents relevant <br/>" + 
						  "<em>" + (rdt-rdr) + "</em> relevant documents unfound <br/>" + 
						  "precision = " + rdr + "/" + dr + " = <em>" + percent(pc) + "%</em><br/>" + 
						  "recall    = " + rdr + "/(" + rdr + "+" + (rdt-rdr) + ") = <em>" + percent(rc) + "%</em><br/>" + 
						  "f-measure = " + "2*(" + percent(pc) + "*" + percent(rc) + ")/(" + percent(pc) + "+" + percent(rc) + ")<br/>" +
						  "          = " + "<em>" + percent((2*(pc*rc))/(pc+rc)) + "%</em>" ;
				
				this.task_tooltip.innerHTML = str ;
			}
			
	
			//this.topScoreLabel.innerHTML = "<em>" + topScore + "</em> points" ;
			//this.docsFoundLabel.innerHTML = "<em>0</em> of <em>" + this.task_docs + "</em>" ;
			//this.docsFoundIndicator.style.width = "0px" ;
			
			this.taskPanel.style.display = "" ;
			
			var message = this.task_desc + "<br/>" + this.task_narr  ;
			this.taskText.innerHTML = message ;
			
			
			koru.searchBox.txtSearch.value = task.getAttribute("initialQuery") ;
			
			var recentQueries = this.xmlHttp.responseXML.getElementsByTagName('recentQueries')[0];
			var bestQueries = this.xmlHttp.responseXML.getElementsByTagName('bestQueries')[0];
			
			koru.searchBox.recentQueries = recentQueries ;
			koru.searchBox.bestQueries = bestQueries ;
			
			
			//koru.queryResultsTray.handleQueryChanged() ;
			
			//var button = document.createElement("a") ;
			//button.innerHTML = "Start Task" ;
			//button.onclick = new Function("koruGame.start()") ;
			
			
			//this.showMessage(this.task_title, message, button) ;
			
			
			//this.task_window = window.open ("task.htm?task=" + this.task_id, "koruGameTask","width=300, height=300") ;
			//this.taskWindow.focus() ;
			
			//window.focus() ;
			
			this.start() ;
		} else {
			this.showMessage("Crap!" , "Looks like there is a problem" + this.xmlHttp.responseXML.xml) ;
		}
	}	
}

function koruGame_start() {
	try {
		if (this.messageBox != null) {
			this.removeChild(this.messageBox) ;
			this.messageBox = null ;
		} 
		
		this.mask.style.display = "none" ;
		//this.removeChild(this.mask) ;
		
		//this.timeBonus = 1000 ;
		//this.updateTimer() ;
		
	} catch ( e ) { 
		logError("koruGame.start.error: " + e ); 
		throw (e) ;
	}
}

function koruGame_pause() {
	
	clearTimeout(this.timer);
	
	var message = "<em>Current Task:</em><p>" + this.task_desc + "</p><p>" + this.task_narr + "</p>" ;
	var button = document.createElement("a") ;
	button.innerHTML = "Resume Game" ;
	button.onclick = new Function("koruGame.resume()") ;
			
	
	this.showMessage("Game Paused", message, button) ;
}

function koruGame_resume() {
	if (this.messageBox != null) {
		this.removeChild(this.messageBox) ;
		this.messageBox = null ;
	} 
		
	this.mask.style.display = "none" ;

	if (this.timeBonus > 0)
		this.updateTimer() ;
}

function koruGame_showMessage(title, message, button) {
	
	try {
		if (this.messageBox != null) {
			this.removeChild(this.messageBox) ;
		} 
		
		this.mask.style.display = "" ;
		
		var messageBox = document.createElement("div") ;
		messageBox.className = "messageBox" ;
		messageBox.style.width = "400px" ;
		//messageBox.style.height = "400px" ;
	
		var header = document.createElement("div") ;
		header.className = "title" ;
		header.innerHTML = title ;
		messageBox.appendChild(header) ;
		
		var tl = document.createElement("div") ;
		tl.className = "border_tl" ;
		messageBox.appendChild(tl) ;
		
		var tr = document.createElement("div") ;
		tr.className = "border_tr" ;
		messageBox.appendChild(tr) ;
		
		var bl = document.createElement("div") ;
		bl.className = "border_bl" ;
		messageBox.appendChild(bl) ;
		
		var br = document.createElement("div") ;
		br.className = "border_br" ;
		messageBox.appendChild(br) ;
		
		var contentArea = document.createElement("div") ;
		contentArea.className = "contentArea" ;
		
		contentArea.innerHTML = message ;
		messageBox.appendChild(contentArea) ;
		
		if (button != null) {
			var buttonContainer = document.createElement("div") ;
			buttonContainer.className = "buttonContainer" ;
			buttonContainer.appendChild(button) ;
			contentArea.appendChild(buttonContainer) ;
		}
		
		this.appendChild(messageBox) ;
		this.messageBox = messageBox ;
			
	} catch ( e ) { 
		logError("koruGame.init.error: " + e ); 
		throw (e) ;
	}
}

function koruGame_showWelcomeMessage() {
	
	var message = "<p>Welcome to the Koru search game. For each round of this game you will be given a task: a topic to investigate." + 
					" The object of the game is for you form the best possible queries for a given task. " +
					" Queries will be scored on how completely and how accurately they retrieve relevant documents. " +
					" Each round will be scored according to your best query and your ability to locate all relevant documents for the task. " +
					"</p> " +
					"<p>" +
					" There is no need to rush, as scores are not based on time or number of queries issued. " + 
					"</p>"
	
	var button = document.createElement("a") ;
	button.innerHTML = "Begin Task" ;
	button.onclick = new Function("koruGame.requestTask() ;") ;				
	
	this.showMessage("Welcome " + this.player, message, button) ;
}


function koruGame_showLoginMessage() {
	
	var message = "<p>Please <a href=\"home.htm\">log in</a> before playing the Koru Game </p> " ;		
	
	this.showMessage("Login Required", message) ;
}

function koruGame_resize() {
	try {
		var w = getDocumentWidth() ;
		var h = getDocumentHeight() ;
		
		this.taskPanel.style.width = (w - 372) + "px" ;
		this.taskText.style.width = (w - 590) + "px" ;
		
		this.currQueryScore.style.left = ((w/2) - 120) + "px" ;
		
		this.style.width = w + " px" ;
		this.style.height = h + " px" ;
		
		this.koru.resize(w, h) ;
	} catch ( e ) { 
		logError("koruGame.resize.error: " + e ); 
		throw (e) ;
	}		
}

function koruGame_documentLocated(id, relevance) {
	try {
		if (relevance == 2) {
			if (!arrayContains(this.docsLocated, id)) {
				this.docsLocated.push(id) ;
			} 
		}
		
		
	} catch ( e ) { 
		logError("koruGame.documentLocated.error: " + e ); 
		throw (e) ;
	}	
}

function koruGame_documentOpened(id, relevance) {
	try {
		
		/*
		if (relevance == 2) {
			if (!arrayContains(this.docsOpened, id)) {
				this.docsOpened.push(id) ;
				
				this.docsFoundLabel.innerHTML = "<em>" + this.docsOpened.length + "</em> of <em>" + this.task_docs + "</em>" ;
				this.docsFoundIndicator.style.width = ((this.docsOpened.length/this.task_docs) * 140) + "px" ;
			}
		}
		
		*/
		
	} catch ( e ) { 
		logError("koruGame.documentOpened.error: " + e ); 
		throw (e) ;
	}	
}

function koruGame_postQueryScore(query, score, ranking, dr, rdr, rdt) {
	
	this.currQueryScore.innerHTML = "<em>" + score + "</em> pts" ;
	
	var rc = rdr/rdt ;
	var pc = rdr/dr ;			
				
	var str = "<em>" + rdr + "</em> of <em>" + dr + "</em> returned documents relevant <br/>" + 
			  "<em>" + (rdt-rdr) + "</em> relevant documents unfound <br/>" + 
			  "precision = " + rdr + "/" + dr + " = <em>" + percent(pc) + "%</em><br/>" + 
			  "recall    = " + rdr + "/(" + rdr + "+" + (rdt-rdr) + ") = <em>" + percent(rc) + "%</em><br/>" + 
			  "f-measure = " + "2*(" + percent(pc) + "*" + percent(rc) + ")/(" + percent(pc) + "+" + percent(rc) + ")<br/>" +
			  "          = " + "<em>" + percent((2*(pc*rc))/(pc+rc)) + "%</em>" ;
			  
	koru.queryResultsTray.score_tooltip.innerHTML = str ;	
	
	if (Number(score) > Number(this.score)) {
		this.score = score;
		
		this.score_query.innerHTML = "Best Query <br /> <em>" + this.score + "</em> pts";
		this.score_rank.innerHTML = ranking;
		this.task_tooltip.innerHTML = str ;
		
	}	
}

function koruGame_requestEndGame() {
	
	var docs = "" ;
	
	for (var i=0; i < this.docsLocated.length; i++) {
  		var doc = this.docsLocated[i];
  		docs = docs + doc ;
    	if (i < this.docsLocated.length - 1) 
    		docs = docs + "," ;
  	}
  	
	var parDocs = newElementAtt('param', '', new Array('name', 'value'), new Array('docsLocated', docs) ) ;	
	var parPlayer = newElementAtt('param', '', new Array('name', 'value'), new Array('player', this.player) ) ;
	var parTask = newElementAtt('param', '', new Array('name', 'value'), new Array('taskId', this.task_id) ) ;
	var parScore = newElementAtt('param', '', new Array('name', 'value'), new Array('score', this.score) ) ;
	
	var paramList = newElement('paramList', parPlayer + parTask + parScore + parDocs);
  	
  	var request = newElementAtt('request', paramList, new Array('lang', 'to', 'type', 'uid'), new Array('en',collection + '/PostScore', 'process', '1'  ) );
  	var message = newElement('message', request );
  	var soapMessage = messageToSOAP(message);
   
  	this.xmlHttp = XmlHttp.create();
  	this.xmlHttp.open("POST", "http://" + serverPath + "/services/localsite", true);
  	this.xmlHttp.onreadystatechange = new Function("koruGame.processEndResponse() ; ") ;
   
	this.xmlHttp.setRequestHeader("SOAPAction", "\"\"");
  	this.xmlHttp.setRequestHeader("Content-Type", "Content-Type: text/xml; charset=utf-8");
   
   	logDebug("Request: " + message) ;
   
  	this.xmlHttp.send(soapMessage);		
}

function koruGame_processEndResponse() {
	if (this.xmlHttp.readyState == 4) {
		
		
		//logDebug(this.xmlHttp.responseXml.xml) ;
		this.task_window.close() ;
		window.location.href="home.htm" ;
	}
}
